using System;
using System.Data;
using System.Data.OleDb;
using System.Xml;
using System.IO;

namespace QidorSpider.Components.Data
{
	public class OleDbDataAccess : AbstractDataAccess
	{
		#region Constructor

		public OleDbDataAccess(OleDbConnection conn)
		{
			this.m_DbConnection = conn;
		}

		public OleDbDataAccess(string connectionString)
		{
			this.m_DbConnection = new OleDbConnection(connectionString);
		}

		#endregion

		#region DataAccess

		#region Support Property & method

		public override DatabaseType DatabaseType
		{
			get { return DatabaseType.OleDBSupported; }
		}

		private OleDbConnection m_DbConnection;
		public override IDbConnection DbConnection
		{
			get
			{
				return m_DbConnection;
			}
		}

		private OleDbTransaction trans = null;
		public override IDbTransaction BeginTransaction()
		{
			trans = m_DbConnection.BeginTransaction();
			return trans;
		}

		#endregion Support Property & method

		#region ExecuteNonQuery

		public override int ExecuteNonQuery(CommandType commandType, string commandText, QueryParameterCollection commandParameters)
		{
			OleDbCommand cmd = new OleDbCommand();
			PrepareCommand(cmd, commandType, commandText, commandParameters);
			int tmpValue = cmd.ExecuteNonQuery();
			SyncParameter(commandParameters);
			cmd.Parameters.Clear();
			return tmpValue;
		}

		#endregion ExecuteNonQuery

		#region ExecuteDataSet

		public override DataSet ExecuteDataset(CommandType commandType, string commandText, QueryParameterCollection commandParameters, DataSet ds, string tableName)
		{
			OleDbCommand cmd = new OleDbCommand();
			PrepareCommand(cmd, commandType, commandText, commandParameters);
			OleDbDataAdapter da = new OleDbDataAdapter(cmd);
			if (Object.Equals(tableName, null) || (tableName.Length < 1))
				da.Fill(ds);
			else
				da.Fill(ds, tableName);

			SyncParameter(commandParameters);
			cmd.Parameters.Clear();
			return ds;
		}

		#endregion ExecuteDataSet

		#region ExecuteReader

		public override IDataReader ExecuteReader(CommandType commandType, string commandText, QueryParameterCollection commandParameters)
		{
			OleDbCommand cmd = new OleDbCommand();
			PrepareCommand(cmd, commandType, commandText, commandParameters);
			OleDbDataReader dr = cmd.ExecuteReader();
			SyncParameter(commandParameters);
			cmd.Parameters.Clear();
			return dr;
		}

		#endregion ExecuteReader

		#region ExecuteScalar

		public override object ExecuteScalar(CommandType commandType, string commandText, QueryParameterCollection commandParameters)
		{
			OleDbCommand cmd = new OleDbCommand();
			PrepareCommand(cmd, commandType, commandText, commandParameters);
			object tmpValue = cmd.ExecuteScalar();
			SyncParameter(commandParameters);
			cmd.Parameters.Clear();
			return tmpValue;
		}

		#endregion ExecuteScalar

		#region ExecuteXmlReader

		public override XmlReader ExecuteXmlReader(CommandType commandType, string commandText, QueryParameterCollection commandParameters)
		{
			DataSet dst = this.ExecuteDataset(commandType, commandText, commandParameters);
			SyncParameter(commandParameters);
			StringReader sreader = new StringReader(dst.GetXml());
			XmlReader reader;
			try
			{
				reader = new XmlTextReader(sreader);
			}
			catch (Exception e)
			{
				sreader.Close();
				throw e;
			}

			return reader;
		}

		#endregion ExecuteXmlReader

		#endregion

		private void PrepareCommand(OleDbCommand cmd, CommandType commandType, string commandText, QueryParameterCollection commandParameters)
		{
			cmd.CommandType = commandType;
			cmd.CommandText = commandText;
			cmd.Connection = this.m_DbConnection;
			cmd.Transaction = trans;
			if ((commandParameters != null) && (commandParameters.Count > 0))
			{
				for (int i = 0; i < commandParameters.Count; i++)
				{
					if (commandParameters[i].DbType == DbType.DateTime)
					{
						OleDbParameter date = new OleDbParameter(commandParameters[i].ParameterName, OleDbType.DBDate); //Date:2005-12-7 21:42:44 //DBDate:2005-12-7
						date.Value = commandParameters[i].Value;
						cmd.Parameters.Add(date);
					}
					else
					{
						commandParameters[i].InitRealParameter(DatabaseType.OleDBSupported);
						cmd.Parameters.Add(commandParameters[i].RealParameter as OleDbParameter);
					}
				}
			}
		}
	}

}

